﻿////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VSCoverageToEmma - Visual Studio Coverage file to Emma converter
// Copyright (c) Kouji Matsui, All rights reserved.
//
// * Redistribution and use in source and binary forms, with or without modification,
//   are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
////////////////////////////////////////////////////////////////////////////////////////////////////

using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace VSCoverageToEmma
{
	public static class Program
	{
		public static int Main(string[] args)
		{
			var assemblyName = typeof(Program).Assembly.GetName();

			Console.WriteLine("Visual Studio Coverage file to Emma converter {0}", assemblyName.Version);
			Console.WriteLine("Copyright (c) Kouji Matsui, All rights reserved.");
			Console.WriteLine();

			try
			{
				var verbose = false;
				string converterName = null;
				string vsCoverageFolderPath = null;
				string binariesFolderPath = null;
				string symbolsFolderPath = null;
				string emmaFolderPath = null;

				var parser = new ArgumentParser();
				var result = parser.
					AddFlagHandler("v", flag => verbose = true).
					AddHandler(arg => converterName = arg).
					AddHandler(arg => vsCoverageFolderPath = Path.GetFullPath(arg)).
					AddHandler(arg => binariesFolderPath = arg, () => binariesFolderPath = vsCoverageFolderPath).
					AddHandler(arg => symbolsFolderPath = arg, () => symbolsFolderPath = binariesFolderPath).
					AddHandler(arg => emmaFolderPath = arg, () => emmaFolderPath = vsCoverageFolderPath).
					Parse(args);

				var converterLoader = new VSConverterLoader();
				converterLoader.Exception += (s, e) =>
					{
						if (verbose == true)
						{
							Console.WriteLine("{0}: {1}: {2}", e.ModulePath, e.Exception.GetType().FullName, e.Exception.Message);
						}
					};

				var converterFolderPath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
				converterLoader.Load(converterFolderPath);

				if (result == false)
				{
					Console.WriteLine("usage: VSCoverageToEmma.exe [-v] <converterName> <vsCoverageFolderPath> [<binariesFolderPath> [<symbolsFolderPath> [<emmaFolderPath>]]]");
					Console.WriteLine("  Available converters: {0}.", converterLoader.Join(", "));

					return 1;
				}

				var vsConverter = converterLoader.Create(converterName, binariesFolderPath, symbolsFolderPath);

				Console.WriteLine("Selected converter: {0}", vsConverter.Name);
				Console.WriteLine();

				var converter = new VSCoverageToEmmaConverter(vsConverter);
				converter.Converted += (sender, e) =>
					{
						Console.WriteLine(
							"VSCoverageToEmma: \"{0}\" --> \"{1}\" [{2} methods]",
							Path.GetFileName(e.CoveragePath),
							Path.GetFileName(e.EmmaPath),
							e.Methods);
					};

				var start = DateTime.Now;

				var methods = converter.ConvertCoverages(vsCoverageFolderPath, emmaFolderPath);

				Console.WriteLine(
					"VSCoverageToEmma: Finished, found total {0} methods, processing {1} seconds.",
					methods,
					(DateTime.Now - start).TotalSeconds);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
				return Marshal.GetHRForException(ex);
			}

			return 0;
		}
	}
}
